
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Audio;
#endregion

namespace Dragoon.BreakIt.View
{
    /// <summary>
    /// This component brings together content and logic elements.
    /// </summary>
    public partial class PlayScene : Microsoft.Xna.Framework.DrawableGameComponent, IPanelContentProvider
    {
        GameEngine _logicEngine;

        SpriteBatch _mainSpriteBatch;
        Texture2D _block,_menuTexture;
        TileMap _tiles;
        SpriteFont _font;

        AudioEngine _audioEngine;
        WaveBank _waves;
        SoundBank _sounds;
        MenuPanel _panel;

        Rectangle _ballTile;
        
        public Rectangle InnerRect;

        public PlayScene(Game game)
            : base(game)
        {
            _tiles = new TileMap();
            _panel = new MenuPanel(Game,this);
            _panel.DrawOrder = DrawOrder + 1;
            Game.Components.Add(_panel);
        }

        internal TileMap Tiles
        {
            get { return _tiles; }
        }

        public override void Initialize()
        {
            base.Initialize();
            _audioEngine = new AudioEngine("content/breakit.xgs");
            _waves = new WaveBank(_audioEngine, "content/MainWaves.xwb");
            _sounds = new SoundBank(_audioEngine, "content/MainSounds.xsb");
            _sounds.PlayCue("ambient");            

        }

        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            const int BALL_SHADOW_WIDTH = 2;
            _mainSpriteBatch = new SpriteBatch(GraphicsDevice);
            if (loadAllContent)
            {
                ContentManager contentMgr = new ContentManager(Game.Services);
                _font = contentMgr.Load<SpriteFont>("content/normal");
                _block = contentMgr.Load<Texture2D>("block");
                _menuTexture = contentMgr.Load<Texture2D>("content/menu");

                _tiles.Texture = contentMgr.Load<Texture2D>("arinoid");

                _ballTile = _tiles.GetBlock(13, 9);
                _ballTile.Inflate(-9, -9);
                // add shadow
                _ballTile.Width += BALL_SHADOW_WIDTH;
                _ballTile.Height += BALL_SHADOW_WIDTH;


                _logicEngine = new GameEngine(
                    new Configuration(
                        contentMgr.Load<Data.Configuration>("content\\GameData"),
                        InnerRect));
                _logicEngine.Ball.ArtWorkTextureSize = _ballTile.Width;
                _logicEngine.Ball.ArtWorkShadowSize = BALL_SHADOW_WIDTH;
                _logicEngine.OnCollision += new EventHandler<CollisionEvent>(OnCollision);
                _logicEngine.OnLevelComplete += new EventHandler<VoidEvent>(OnLevelComplete);
            }
        }

        void OnLevelComplete(object sender, VoidEvent e)
        {
            _sounds.PlayCue("leveldone");
        }

        void OnCollision(object sender, CollisionEvent e)
        {
            if (e.Target is Wall)
            {
                if ((e.Target as Wall).Side == Side.Bottom)
                    _sounds.PlayCue("eatball");
                else
                    _sounds.PlayCue("bouncewall");
            }
            else if (e.Target is Block)
            {
                Block blockHit = e.Target as Block;
                if (blockHit.IsActive)
                    _sounds.PlayCue("bounceblock");
                else
                    _sounds.PlayCue("popblock");

            }
            else if (e.Source is Ball && e.Target is Paddle)
            {
                _sounds.PlayCue("bouncepaddle");
            }
            else if (e.Source is Capsule &&  e.Target is Paddle)
            {
                _sounds.PlayCue("eatcapsule");
            }
        }

        static readonly Vector2 V_TEXT = new Vector2(50, 10);
        static readonly Vector2 V_TEXT_SHADOW = V_TEXT + new Vector2(4, 4);
        public override void Draw(GameTime time)
        {
            
            _mainSpriteBatch.Begin();

            _mainSpriteBatch.Draw(_tiles.Texture,
                _logicEngine.Ball.DrawDestinationAt(time),
                _ballTile, Color.White);
            
            // draw blocks
            foreach (Block idxBlock in _logicEngine.ActiveLevel.Blocks)
            {
                if (idxBlock.IsActive)
                {
                    _mainSpriteBatch.Draw(
                        _tiles.Texture,
                        idxBlock.Position, idxBlock.Type.ImageSourceArea, Color.White);
                }
            }
            // draw capsules -- "floating" on blocks
            foreach (Block idxBlock in _logicEngine.ActiveLevel.Blocks)
            {
                if (idxBlock.HasCapsule && idxBlock.HiddenCapsule.IsVisible)
                {
                    _mainSpriteBatch.Draw(
                        _tiles.Texture,
                        idxBlock.HiddenCapsule.Position,
                        idxBlock.HiddenCapsule.ImageSourceArea,
                        Color.White);
                }
            }


            /// draw the paddle
            _mainSpriteBatch.Draw(_tiles.Texture, _logicEngine.Paddle.Position, _logicEngine.Paddle.ImageSourceArea, Color.White);

#if TRACE
            foreach (ICollidable c in _logicEngine.Collidables)
            {
                //if (c is Wall && (c as Wall).Side == Side.Right)
                {
                    _mainSpriteBatch.Draw(_block,
                        new Rectangle(
                        (int)c.Bounds.Min.X,
                        (int)c.Bounds.Min.Y,
                        (int)c.Bounds.Max.X - (int) c.Bounds.Min.X,
                        (int)c.Bounds.Max.Y - (int) c.Bounds.Min.Y),
                        Color.White);
                }
            }
#endif

            string text = string.Format("Level {0:#00} | Lives {3:#00} | Bonus {2:#000} | Score {1:#000000}",
                _logicEngine.LevelNumber, _logicEngine.Score, _logicEngine.Bonus, _logicEngine.Lives);
            _mainSpriteBatch.DrawString(_font, text, V_TEXT_SHADOW, Color.Black);
            _mainSpriteBatch.DrawString(_font, text, V_TEXT, Color.Silver);
            _mainSpriteBatch.End();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime time)
        {
            _logicEngine.Update(time);
            _audioEngine.Update();
            _logicEngine.HandleInput(time);
            base.Update(time);
        }

        #region IPanelContentProvider Members

        public Menu Menu
        {
            get
            {
                return _logicEngine.ActiveMenu;
            }
        }

        public SpriteFont MenuFont
        {
            get { return _font; }
        }

        public Texture2D MenuBackdrop
        {
            get { return _menuTexture; }
        }

        #endregion
    }
}



